package net.tygzs.minerpg.Configuration;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import net.tygzs.minerpg.Configuration.pvp.PVPConfig;
import net.tygzs.minerpg.Configuration.Item.RPGItem;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import me.dpohvar.powernbt.PowerNBT;
import me.dpohvar.powernbt.api.NBTCompound;
import me.dpohvar.powernbt.api.NBTManager;
import net.milkbowl.vault.economy.Economy;
import net.tygzs.minerpg.Configuration.GuildConfig.GuildConfig;
import net.tygzs.minerpg.Configuration.Item.RPGItem.RPGItemType;
import net.tygzs.minerpg.Configuration.packet.Packet;
import net.tygzs.minerpg.Configuration.world.WorldConfig;
import net.tygzs.minerpg.Main;
import net.tygzs.minerpg.keyBoardListener.keyBoardListener;
import net.tygzs.minerpg.timer.Timer;
import static org.bukkit.Bukkit.getServer;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.RegisteredServiceProvider;

/**
 *
 * @author thtTNT
 */
public class PluginConfig
{

    private final NBTManager nbtManager = PowerNBT.getApi();
    private final Map<String, RPGItem> rpgItems = new HashMap<>();
    private final Map<String, Packet> packets = new HashMap<>();
    private PVPConfig pvpConfig = new PVPConfig();
    private TeamConfig teamConfig = new TeamConfig();
    private Timer timer;
    private Economy economy;
    private ServerConfig serverConfig = new ServerConfig();
    private WorldConfig worldConfig = new WorldConfig();
    private GuildConfig guildConfig = new GuildConfig();

    public PluginConfig()
    {
        load();
        keyBoardListener.start();
        SystemLoad();
    }

    public void reload()
    {
        Main.getPlugin().reloadConfig();
        load();
        this.pvpConfig = new PVPConfig();
        this.teamConfig = new TeamConfig();
        this.serverConfig = new ServerConfig();
        this.worldConfig = new WorldConfig();
        this.guildConfig = new GuildConfig();
    }

    private void load()
    {
        if (!Main.getPlugin().getDataFolder().exists())
        {
            Main.getPlugin().getDataFolder().mkdirs();
        }
        File file = new File(Main.getPlugin().getDataFolder(), "config.yml");
        if (!file.exists())
        {
            Main.getPlugin().saveDefaultConfig();
        }
        file = new File(Main.getPlugin().getDataFolder(), "items");
        if (!file.exists())
        {
            file.mkdirs();
        }
        for (File ItemFile : file.listFiles())
        {
            FileConfiguration config = YamlConfiguration.loadConfiguration(ItemFile);
            RPGItem ri = new RPGItem();
            ri.setDamage(config.getInt("Damage"));
            ri.setMaxDur(config.getInt("MaxDur"));
            ri.setDur(config.getInt("MaxDur"));
            ri.setDisPlayName(config.getString("DisPlayName"));
            ri.setDisPlayID(config.getInt("ID"));
            ri.setDisPlayDur((short) config.getInt("DisplayDur"));
            ri.setLores(config.getStringList("Lores"));
            ri.setType(RPGItemType.getRPGItemType(config.getString("Type")));
            rpgItems.put(config.getString("Name"), ri);
        }
        file = new File(Main.getPlugin().getDataFolder(), "packets");
        if (!file.exists())
        {
            file.mkdirs();
        }
        for (File PacketFile : file.listFiles())
        {
            FileConfiguration config = YamlConfiguration.loadConfiguration(PacketFile);
            Packet packet = new Packet();
            packet.setName(config.getString("Name"));
            packet.setNewPlayerPacket(config.getBoolean("NewPlayerPacket"));
            if (config.contains("times"))
            {
                ConfigurationSection section = config.getConfigurationSection("times");
                Set<String> names = section.getKeys(false);
                for (String name : names)
                {
                    packet.setTime(name, section.getInt(name));
                }
            }
            int index = 1;
            while (config.contains("items." + index))
            {
                ItemStack is = config.getItemStack("items." + index);
                if (config.contains("nbt." + index))
                {
                    NBTCompound nbt = readNBT("nbt." + index, config, new NBTCompound());
                    this.getNBTManager().write(is, nbt);
                }
                packet.getItems().add(is);
                index++;
            }
            packets.put(packet.getName(), packet);
        }
    }

    public void save()
    {
        File file = new File(Main.getPlugin().getDataFolder(), "items");
        file.delete();
        file.mkdirs();
        Set<String> ItemNames = rpgItems.keySet();
        for (String ItemName : ItemNames)
        {
            try
            {
                File ItemFile = new File(file, ItemName + ".yml");
                file.createNewFile();
                RPGItem ri = rpgItems.get(ItemName);
                FileConfiguration config = YamlConfiguration.loadConfiguration(file);
                config.set("DisPlayName", ri.getDisPlayName());
                config.set("Damage", ri.getDamage());
                config.set("Name", ItemName);
                config.set("MaxDur", ri.getMaxDur());
                config.set("ID", ri.getDisPlayID());
                config.set("DisplayDur", ri.getDisPlayDur());
                config.set("Lores", ri.getLores());
                config.set("Type", ri.getType().name());
                config.save(ItemFile);
            } catch (IOException ex)
            {
                Logger.getLogger(PluginConfig.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        file = new File(Main.getPlugin().getDataFolder(), "packets");
        if (!file.exists())
        {
            file.mkdirs();
        }
        for (File f : file.listFiles())
        {
            f.delete();
        }
        Set<String> packetnames = packets.keySet();
        for (String packetname : packetnames)
        {
            Packet packet = packets.get(packetname);
            try
            {
                File PacketFile = new File(file, packet.getName() + ".yml");
                PacketFile.createNewFile();
                FileConfiguration config = YamlConfiguration.loadConfiguration(PacketFile);
                int index = 1;
                for (ItemStack item : packet.getItems())
                {
                    String path = "items." + index;
                    config.set(path, item);
                    NBTCompound nbt = this.getNBTManager().read(item);
                    if (nbt != null)
                    {
                        config = saveNBT("nbt." + index, config, nbt);
                    }
                    index++;
                }
                config.set("Name", packet.getName());
                config.set("NewPlayerPacket", packet.isNewPlayerPacket());
                Set<String> names = packet.getTimes().keySet();
                for (String name : names)
                {
                    config.set("times." + name, packet.getTime(name));
                }
                config.save(PacketFile);
            } catch (IOException ex)
            {
                Logger.getLogger(PluginConfig.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        this.SystemSave();
        this.getPVPConfig().save();
        this.getTeamConfig().save();
        this.getGuildConfig().save();
    }

    public NBTManager getNBTManager()
    {
        return this.nbtManager;
    }

    public RPGItem CreateItem(String name)
    {
        if (rpgItems.containsKey(name))
        {
            return rpgItems.get(name);
        }
        RPGItem ri = new RPGItem();
        rpgItems.put(name, ri);
        return null;
    }

    public RPGItem getItem(String name)
    {
        if (rpgItems.containsKey(name))
        {
            return rpgItems.get(name);
        }
        return null;
    }

    public boolean removeItem(String ItemName)
    {
        if (rpgItems.containsKey(ItemName))
        {
            rpgItems.remove(ItemName);
            return true;
        }
        return false;
    }

    public Set<String> getItems()
    {
        return rpgItems.keySet();
    }

    public Map<String, Packet> getPackets()
    {
        return this.packets;
    }

    private FileConfiguration saveNBT(String path, FileConfiguration config, NBTCompound nbt)
    {
        Set<String> keys = nbt.keySet();
        for (String key : keys)
        {
            Object vaule = nbt.get(key);
            if (vaule.getClass() == me.dpohvar.powernbt.nbt.NBTTagCompound.class)
            {
                config = saveNBT(path + "." + key, config, nbt);
                continue;
            }
            config.set(path + "." + key, vaule);
        }
        return config;
    }

    private NBTCompound readNBT(String path, FileConfiguration config, NBTCompound nbt)
    {
        Set<String> keys = config.getConfigurationSection(path).getKeys(false);
        for (String key : keys)
        {
            if (config.isConfigurationSection(path + "." + key))
            {
                NBTCompound nbtC = readNBT(path + "." + key, config, new NBTCompound());
                nbt.put(key, nbtC);
                continue;
            }
            nbt.put(key, config.get(path + "." + key));
        }
        return nbt;
    }

    public PVPConfig getPVPConfig()
    {
        return this.pvpConfig;
    }

    public TeamConfig getTeamConfig()
    {
        return this.teamConfig;
    }

    private void SystemLoad()
    {
        File file = new File(Main.getPlugin().getDataFolder(), "system.yml");
        long time = 0;
        if (file.exists())
        {
            FileConfiguration config = YamlConfiguration.loadConfiguration(file);
            if (config.contains("time"))
            {
                time = config.getLong("time");
            }
        }
        this.timer = new Timer(time);
    }

    public void SystemSave()
    {
        try
        {
            File file = new File(Main.getPlugin().getDataFolder(), "system.yml");
            if (!file.exists())
            {
                file.createNewFile();
            }
            FileConfiguration config = YamlConfiguration.loadConfiguration(file);
            config.set("time", this.timer.getServerTime());
            config.save(file);
        } catch (IOException ex)
        {
            Logger.getLogger(PluginConfig.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Timer getTimer()
    {
        return this.timer;
    }

    private void setupEconomy()
    {
        RegisteredServiceProvider<Economy> economyProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
        if (economyProvider != null)
        {
            economy = economyProvider.getProvider();
        } else
        {
            Main.getPlugin().getLogger().info("载入经济系统出现错误!");
        }
    }

    public Economy getEconomy()
    {
        return this.economy;
    }

    public ServerConfig getServerConfig()
    {
        return this.serverConfig;
    }

    public WorldConfig getWorldConfig()
    {
        return this.worldConfig;
    }

    public GuildConfig getGuildConfig()
    {
        return this.guildConfig;
    }
}
